<?php
/**
 * 声网 API
 */

namespace App\Services\Agora;


use App\Services\Configs\DefaultService;

class BaseService
{
    protected $url = null;// 接口
    protected $key = null;// 客户 ID
    protected $secret = null;// 客户密钥
    protected $appid = null;// 项目应用 ID
    protected $appCertificate = null;// 项目证书
    protected $token = null;// 令牌
    private $errMessage = null;


    public function __construct()
    {
        $config = $this->getConfig();
        $this->url = $config['url'];
        $this->key = $config['key'];
        $this->secret = $config['secret'];
        $this->appid = $config['appid'];
        $this->appCertificate = $config['appCertificate'];
        $this->token = $this->httpAuth();
    }

    /**
     * 获取配置信息
     * @return mixed
     * @throws \Exception
     */
    private function getConfig()
    {
        $config = new DefaultService();
        $data = $config->first(DefaultService::AGORA_AV);
        if (!$data) {
            throw new \Exception('找不到配置 ' . DefaultService::AGORA_AV);
        }
        return $data;
    }

    /**
     * 获取token
     * @return string|null
     */
    public function getToken()
    {
        return $this->token;
    }

    /**
     * 发起请求
     * @param $uri 资源路径
     * @param array $param 请求参数
     * @param string $type 请求类型
     * @return bool|mixed|string
     */
    protected function request($uri, $param = [], $type = "POST")
    {
        $url = $this->url . $uri;
        if (strtolower($type) == 'get' && !empty($param)) {
            $url .= '?' . http_build_query($param);
            $param = [];
        }
        $res = $this->postCurl($url, json_encode($param), [$this->token, 'Content-Type: application/json'], $type);
        if (!isset($res['success']) || $res['success'] != true) {
            $this->errMessage = $res['message'] ?? null;
        }
        return $res;
    }

    /**
     * 获取错误信息
     * @return string
     */
    public function getErrMessage()
    {
        return $this->errMessage;
    }

    /**
     * HTTP 认证
     * @return string
     */
    private function httpAuth()
    {
        // 基于 PHP 实现的 HTTP 基本认证示例，使用 RTC 的服务端 RESTful API
        // 拼接客户 ID 和客户密钥
        $credentials = $this->key . ":" . $this->secret;
        // 使用 base64 进行编码
        $base64Credentials = base64_encode($credentials);
        // 创建 authorization header
        $header = "Authorization: Basic " . $base64Credentials;
        return $header;
    }

    /**
     * 请求主体
     * @param $url
     * @param $body
     * @param $header
     * @param string $type
     * @return bool|mixed|string
     */
    private function postCurl($url, $body, $header, $type = "POST")
    {
        //1.创建一个curl资源
        $ch = curl_init();
        //2.设置URL和相应的选项
        curl_setopt($ch, CURLOPT_URL, $url);//设置url
        //设置为false,只会获得响应的正文(true的话会连响应头一并获取到)
        curl_setopt($ch, CURLOPT_HEADER, 0);
        //设置发起连接前的等待时间，如果设置为0，则无限等待。
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        //将curl_exec()获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $body);//全部数据使用HTTP协议中的"POST"操作来发送。
        //设置请求头
        if (count($header) > 0) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        //上传文件相关设置
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);// 从证书中检查SSL加密算
        //3)设置提交方式
        switch ($type) {
            case "GET":
                curl_setopt($ch, CURLOPT_HTTPGET, true);
                break;
            case "POST":
                curl_setopt($ch, CURLOPT_POST, true);
                break;
            case "PUT"://使用一个自定义的请求信息来代替"GET"或"HEAD"作为HTTP请求。这对于执行"DELETE" 或者其他更隐蔽的HTT
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
                break;
            case "DELETE":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
                break;
        }
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)'); // 模拟用户使用的浏览器
        $res = curl_exec($ch);
        $result = json_decode($res, true);
        //4.关闭curl资源，并且释放系统资源
        curl_close($ch);
        if (empty($result)) {
            return $res;
        } else {
            return $result;
        }
    }
}
